package com.wwmz.pattern.factory.example;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.util.Properties;

/**
 * 自定义连接池getInstance()返回唯一实例，第一次调用时将执行构造函数
 * 构造函数Pool()调用驱动装在loadDrivers()函数；连接池创建createPool()函数  loadFrivers()装载驱动
 * createPool()创建连接池getConnection()返回一个连接实例 getConnection(long time)添加时间限制
 * freeConnection(Connection con)将con连接实例返回到连接池 getnum()返回空闲连接数
 *
 * Created by wumz on 2020/9/16 14:48
 */
public abstract class Pool {
    public String propertiesName = "connection-INF.properties";

    private static Pool instance = null; //定义唯一实例

    protected int maxConnect = 100; //最大连接数

    protected int normalConnect = 10; //保持连接数

    protected String driverName = null; //驱动名称

    protected Driver driver = null; //驱动变量

    /**
     * 私有构造，不允许外界访问
     */
    protected Pool(){
        try {
            init();
            loacDrivers(driverName);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 初始化所有从配置文件中读取的成员变量
     */
    protected void init() throws IOException {
        InputStream inputStream = Pool.class.getResourceAsStream(propertiesName);
        Properties properties = new Properties();
        properties.load(inputStream);
        this.driverName = properties.getProperty("driverName");
        this.maxConnect = Integer.parseInt(properties.getProperty("maxConnect"));
        this.normalConnect = Integer.parseInt(properties.getProperty("normalConnect"));
    }

    /**
     * 装载和注册所有JDBC驱动程序
     * @param driverName    接受驱动字符串
     */
    protected void loacDrivers(String driverName){
        try {
            driver = (Driver)Class.forName(driverName).newInstance();
            DriverManager.registerDriver(driver);
            System.out.println("成功注册JDBC驱动程序"+driverName);
        }catch (Exception e){
            System.out.println("无法注册JDBC驱动程序"+driverName+" error:"+e);
            e.printStackTrace();
        }
    }

    /**
     * 创建连接池
     */
    public abstract void createPool();

    /**
     * 返回数据库连接池Pool的实例
     * @return
     * @throws Exception
     */
    public static synchronized Pool getInstance() throws Exception{
        if (instance == null){
            instance.init();
            instance = (Pool)Class.forName("org.e_book.sqlhelp.Pool").newInstance();
        }
        return instance;
    }

    /**
     * 获得一个可用的连接，如果没有则创建一个连接，并且小于最大连接限制
     */
    public abstract Connection getConnection();

    /**
     * 获得一个连接, 有时间限制
     */
    public abstract Connection getConnection(long time);

    /**
     * 将连接对象返回给连接池
     */
    public abstract void freeConnection(Connection connection);

    /**
     * 返回当前空闲连接数
     */
    public abstract int getNum();

    /**
     * 返回当前工作的连接数
     */
    public abstract int getNumActive();

    /**
     * 关闭所有连接，撤销驱动注册（单例）
     */
    protected synchronized void release(){
        try {
            DriverManager.deregisterDriver(driver);
            System.out.println("撤销 JDBC驱动程序" + driver.getClass().getName());
        }catch (Exception e){
            System.out.println("无法撤销 JDBC驱动程序" + driver.getClass().getName());
            e.printStackTrace();
        }
    }



}
